package com.blq.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.BankcardExtInfo;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.blq.common.core.domain.entity.SysDept;
import com.blq.common.core.domain.entity.SysDeptInfo;
import com.blq.common.core.domain.entity.SysUser;
import com.blq.common.exception.ServiceException;
import com.blq.common.utils.AmountCalUtils;
import com.blq.common.utils.CertHttpUtil;
import com.blq.common.utils.StringUtils;
import com.blq.common.core.page.TableDataInfo;
import com.blq.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blq.pay.AliPayConstants;
import com.blq.pay.service.IWxPayService;
import com.blq.system.mapper.SysDeptInfoMapper;
import com.blq.system.mapper.SysDeptMapper;
import com.blq.system.mapper.SysUserMapper;
import com.blq.system.service.ISysConfigService;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.blq.web.domain.bo.UserMoneyItemBo;
import com.blq.web.domain.vo.UserMoneyItemVo;
import com.blq.web.domain.UserMoneyItem;
import com.blq.web.mapper.UserMoneyItemMapper;
import com.blq.web.service.IUserMoneyItemService;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 钱包明细Service业务层处理
 *
 * @author zeh
 * @date 2023-06-25
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserMoneyItemServiceImpl extends ServiceImpl<UserMoneyItemMapper,UserMoneyItem> implements IUserMoneyItemService {

    private final UserMoneyItemMapper baseMapper;
    private final ISysConfigService sysConfigService;
    private final SysUserMapper sysUserMapper;
    private final SysDeptMapper sysDeptMapper;
    private final SysDeptInfoMapper sysDeptInfoMapper;

    /**
     * 查询钱包明细
     */
    @Override
    public UserMoneyItemVo queryById(Long itemId){
        return baseMapper.selectVoById(itemId);
    }

    /**
     * 查询钱包明细列表
     */
    @Override
    public TableDataInfo<UserMoneyItemVo> queryPageList(UserMoneyItemBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<UserMoneyItem> lqw = buildQueryWrapper(bo);
        Page<UserMoneyItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询钱包明细列表
     */
    @Override
    public List<UserMoneyItemVo> queryList(UserMoneyItemBo bo) {
        LambdaQueryWrapper<UserMoneyItem> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询提现到银行卡待支付列表
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<UserMoneyItemVo> queryPageBankList(UserMoneyItemBo bo, PageQuery pageQuery) {
//        bo.setType(2);
        bo.setClassify(3);
        bo.setState(1);
        /*pageQuery.setOrderByColumn("createTime");
        pageQuery.setIsAsc("asc");*/
        LambdaQueryWrapper<UserMoneyItem> lqw = buildQueryWrapper(bo);
        Page<UserMoneyItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    @Transactional
    public boolean handleBankCash(UserMoneyItemBo bo) {
        UserMoneyItem moneyItem = baseMapper.selectById(bo.getItemId());
        if (moneyItem == null) {
            throw new ServiceException("此条记录不存在");
        }
        if (moneyItem.getState() != 1) {
            throw new ServiceException("此条记录已处理完成，请勿重复处理");
        }
        if (bo.getState() == 2) {
            moneyItem.setState(2);
            baseMapper.updateById(moneyItem);
        } else if (bo.getState() == 3) {
            // 如果是作废此条用户提现记录，则提现金额退回用户钱包
            if (moneyItem.getType() == 2) {
                BigDecimal money = moneyItem.getMoney();
                if (moneyItem.getObjType() == 1) {
                    SysUser sysUser = sysUserMapper.selectById(moneyItem.getObjId());
                    if (sysUser == null) {
                        throw new ServiceException("记录所属对象不存在");
                    }
                    // 更新账户余额
                    sysUser.setMoney(sysUser.getMoney().add(money));
                    sysUserMapper.updateById(sysUser);
                } else {
                    SysDept sysDept = sysDeptMapper.selectById(moneyItem.getItemId());
                    if (sysDept == null) {
                        throw new ServiceException("记录所属对象不存在");
                    }
                    // 更新账户余额
                    sysDept.setMoney(sysDept.getMoney().add(money));
                    sysDeptMapper.updateById(sysDept);
                }
            }
            moneyItem.setState(3);
            baseMapper.updateById(moneyItem);
        } else {
            throw new ServiceException("提交处理请求参数错误！");
        }
        return true;
    }

    private LambdaQueryWrapper<UserMoneyItem> buildQueryWrapper(UserMoneyItemBo bo) {
//        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<UserMoneyItem> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getObjId() != null, UserMoneyItem::getObjId, bo.getObjId());
        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), UserMoneyItem::getTitle, bo.getTitle());
        lqw.eq(bo.getType() != null, UserMoneyItem::getType, bo.getType());
        lqw.eq(bo.getClassify() != null, UserMoneyItem::getClassify, bo.getClassify());
        lqw.eq(bo.getState() != null, UserMoneyItem::getState, bo.getState());
        lqw.eq(bo.getRelationId() != null, UserMoneyItem::getRelationId, bo.getRelationId());
        return lqw;
    }

    /**
     * 新增钱包明细
     */
    @Override
    public Boolean insertByBo(UserMoneyItemBo bo) {
        UserMoneyItem add = BeanUtil.toBean(bo, UserMoneyItem.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setItemId(add.getItemId());
        }
        return flag;
    }

    /**
     * 修改钱包明细
     */
    @Override
    public Boolean updateByBo(UserMoneyItemBo bo) {
        UserMoneyItem update = BeanUtil.toBean(bo, UserMoneyItem.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(UserMoneyItem entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除钱包明细
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询账户总收益和未到账金额
     * @param objId
     * @return
     */
    @Override
    public JSONObject queryTotalAndFreeze(Long objId) {
        return baseMapper.selectTotalAndFreezeByObjId(objId);
    }

    @Override
    public boolean cashMoneys(Long objId, BigDecimal money, Integer classify) {
        //是否允许提现
        String isRate = sysConfigService.selectConfigByKey("wallet.cash.open");
        if ("否".equals(isRate)) {
            throw new ServiceException("当前系统未开启提现");
        }
        if (money == null || money.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("请不要输入小于0的数字,请输入正确的提现金额！");
        }
        SysUser sysUser = sysUserMapper.selectById(objId);
        if (sysUser != null) {
            if (money.compareTo(sysUser.getMoney()) > 0) {
                throw new ServiceException("提现金额大于钱包余额，请输入正确的提现金额！");
            }
            if (classify == 1) {
                if (StringUtils.isBlank(sysUser.getOpenid())) {
                    throw new ServiceException("请先完善提现微信信息");
                }
                // 执行微信转账
                return wxCash(sysUser, money, classify, 2);
            } else if (classify == 2) {
                if (StringUtils.isBlank(sysUser.getZhiFuBaoName()) || StringUtils.isBlank(sysUser.getZhiFuBao())) {
                    throw new ServiceException("请先完善支付宝信息");
                }
                return zfbCash(sysUser, money, classify, 2, null);
            } else if (classify == 3) {
                if (StringUtils.isBlank(sysUser.getPayBankUser()) || StringUtils.isBlank(sysUser.getPayBankCard()) ||
                        StringUtils.isBlank(sysUser.getPayBankName()) || StringUtils.isBlank(sysUser.getPayBankPhone())) {
                    throw new ServiceException("请先完善银行卡信息");
                }
                return bankCash(sysUser, money, classify);
                // 通过支付宝转账到银行卡方式提现（未开通）
                // return zfbCash(sysUser, money, classify, 2, null);
            } else {
                throw new ServiceException("提现方式参数错误");
            }
        } else {
            SysDept sysDept = sysDeptMapper.selectById(objId);
            if (sysDept != null) {
                if (money.compareTo(sysDept.getMoney()) > 0) {
                    throw new ServiceException("提现金额大于钱包余额，请输入正确的提现金额！");
                }
//                SysDeptInfo deptInfo = sysDept.getDeptInfo();
                SysDeptInfo deptInfo = sysDeptInfoMapper.selectById(sysDept.getDeptId());
                sysDept.setDeptInfo(deptInfo);
                if (classify == 2) {
                    if (StringUtils.isBlank(deptInfo.getZhiFuBaoName()) || StringUtils.isBlank(deptInfo.getZhiFuBao())) {
                        throw new ServiceException("请先完善支付宝信息");
                    }
                    return zfbCash(sysDept, money, classify, 2, null);
                } else if (classify == 3) {
                    if (StringUtils.isBlank(deptInfo.getPayBankUser()) || StringUtils.isBlank(deptInfo.getPayBankCard()) ||
                            StringUtils.isBlank(deptInfo.getPayBankName())) {
                        throw new ServiceException("请先完善银行卡信息");
                    }
                    return bankCash(sysDept, money, classify);
                // return zfbCash(sysDept, money, classify, 2, null);
                } else {
                    throw new ServiceException("提现方式参数错误");
                }
            }
        }
        return false;
    }

    @Override
    @Transactional
    public boolean bankCash(SysUser sysUser, BigDecimal money, Integer classify) {
        // 生成钱包明细
        UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName(), 1,
                "零钱提现", StringUtils.format("零钱提现到银行卡{}元", money),
                2, classify, money, 1);
        baseMapper.insert(moneyItem);
        // 更新账户余额
        sysUser.setMoney(sysUser.getMoney().subtract(money));
        sysUserMapper.updateById(sysUser);
//        throw new ServiceException("提现成功！提现金额预计将在1至3天内到账。");
        return true;
    }

    @Override
    @Transactional
    public boolean bankCash(SysDept sysDept, BigDecimal money, Integer classify) {
        // 生成钱包明细
        UserMoneyItem moneyItem = new UserMoneyItem(sysDept.getDeptId(), sysDept.getDeptName(), 2,
                "零钱提现", StringUtils.format("零钱提现到银行卡{}元", money),
                2, classify, money, 1);
        baseMapper.insert(moneyItem);
        // 更新账户余额
        sysDept.setMoney(sysDept.getMoney().subtract(money));
        sysDeptMapper.updateById(sysDept);
        return true;
//        throw new ServiceException("提现成功！提现金额预计将在1至3天内到账。");
    }

    @Override
    public boolean zfbCash(SysUser sysUser, BigDecimal money, Integer classify, Integer type, Long itemId) {
        // 暂不开通支付宝转银行卡
        if (classify == 3) {
            return false;
        }
        String _classify = classify == 3 ? "银行卡" :"支付宝";
        if (type == 2) {
            // 生成钱包明细
            UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName(), 1,
                    "零钱提现", StringUtils.format("零钱提现到{}{}元", _classify, money),
                    2, classify, money, 1);
            baseMapper.insert(moneyItem);
            itemId = moneyItem.getItemId();
        }
        String zfbAppid = sysConfigService.selectConfigByKey("zfb.sh.appid");
        String certPath = sysConfigService.selectConfigByKey("zfb.cert.path");//应用相关支付宝证书存放路径
        String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4pdDiiYJsGkim1auBc1qVzxcdDuPJEwTmTurlwCyHLVNpKNY6I/hhMmvYFTS8ZsnHMWhxuAOhDLMCaPHxNW2T0wxEX8ZXZwxgNW8JHqxILDuRAgGfKK+5NBUZ1ew4oBMZEpDchkqLCwp+eGo8PtCBEZaIe+Iv42VSIs8najv/oPajT0G13CoCUgJhhsh2kZWC6vtm4kR6cSItGvRi847mgAxlQI4HEDG7o0PfvDmAM4ha9DfxTomlkrKhE6NY+Ms7DbmPDyr/YECJ780goYKwS0eSCIOAXdHI84v4mRJpsu5qdzic/ChpD1yaJJ9nXPIX8xMoF6HEM1jgr95+SBwHAgMBAAECggEAdVGlrsn/+/+XOal5Fv7cB2NVJDlZsWBMNKjfxqqboCfEX4R62OYR4m/O5bRTlYEZo15ZJifs5l7TPiy/zKpNvSbTHH5d3xqyWk6ZBgpfHFw+XJwRu7Z2MA5PeeLZ/AB5Ie0R7YvFwSJ6wHBxz2V5xQgPxRgxVov8zHshc8Gj7X6b7WCvNCHZA26lUSU53MHDxivno/tpOAqWhL1rHrwL+vEaoZKkd+P1L8CEbaRH5UpNnm9Pn0ubCxbPcy/Vk4OdsrP6I4eqpkrRU1WZFgmLZZ3iXudrZEnn1QlhZB6Xgu5WyXCFEnSn3Es/3vdARBucLyfUO9ABDmneY6s4aYI6AQKBgQDakuc0OzXzLl1M4uc48b2BX1uEBQkeKI8/xcAZYy6ikSo0xI4P5qYZtxzFQsdJn+pz7CXZGvWHwyaWl94rI8dNf3YYTl0zJ23rrfaN1TaJEB7SLpOm98p8T2YrHqKcAhvgocDtYo5jW7o9PspBg3+ujC2A63zNGUulR5LSUtF7ZwKBgQDYQ8Zbv+SlQvcQrpxYXzreblI/EV2FBqhMpOiNzgAsLgGntOEU28BtxVa2M6aNvtPCY+gBymzpi/JENONgrXCJcuOKFx/BwReEO/yD7rDbIxea1j1eTk9JrWJaOh3WDqFfLx3I+NtJf1IYwK0ls7CafEEZa3NbC+0VC7N5hlaWYQKBgQCVR6/Q5H+8TvY6BN6W7cPYECCY0jef+WOc0pqYvDylmy+QSo4cHhNjjMSBlVI23plqAub2mIsI5if8wkxielUsgNlPUHYm8c8JIA88X1qX0gK62kTNzH7m1/OXj5zPoEEZ8l+pwZ4uDf/sxG2uwPj7ZZHOcwcRrS0U/QUx0I5yEQKBgB9OWFWJxsCBnCBHFozYZD40vCUzD1WlbBGEQcHdUzsSAd1UGs0ZLpb1XSMNAQw91ouqSLiRpAh+4Lgs68lf8g2DmxqvVEKJAC19PYWftOxT/SPF5aZUMbgZqEYlaZJGFeggevBPzfaqvqiko6v0ghkq6YWTf2RrqotEYVuzLa+hAoGBAJ0vHmj9S8oVmgXzj2gznzoMev6KgnMyLnGlmroFKONtipFmL+BYPrx7JDlPOKE7ymtR3c9tojsIfDtuLeICMPpW9UXf2YrwxQBBPXpWHeHdUjCRpsY6cv1vQxiOTAR0Xk7OTDK9XGLJe2esH8+UQG3sXyut2uvkiKFJaJ4tKcg+";
        AlipayFundTransUniTransferResponse response;
        try {
            CertAlipayRequest alipayConfig = new CertAlipayRequest();
            alipayConfig.setPrivateKey(privateKey);
            alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
            alipayConfig.setAppId(zfbAppid);
            alipayConfig.setCharset("UTF8");
            alipayConfig.setSignType("RSA2");
            alipayConfig.setEncryptor("");
            alipayConfig.setFormat("json");
            alipayConfig.setCertPath(certPath + File.separator + "appCertPublicKey.crt");//<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->
            alipayConfig.setAlipayPublicCertPath(certPath + File.separator + "alipayCertPublicKey_RSA2.crt");//"<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->"
            alipayConfig.setRootCertPath(certPath + File.separator + "alipayRootCert.crt");//"<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt -->");
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
            AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
            model.setOutBizNo(String.valueOf(itemId));
            model.setRemark("易用能零钱提现");
            model.setBizScene("DIRECT_TRANSFER");
            Participant payeeInfo = new Participant();
            model.setTransAmount(String.valueOf(money));
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
            if (classify == 3) {
                model.setProductCode("TRANS_BANKCARD_NO_PWD");
                model.setBusinessParams("{\"withdraw_timeliness\":\"T0\"} ");//注意：withdraw_timeliness 为转账到银行卡的预期到账时间，不传默认T+1到账。
                payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
                payeeInfo.setIdentity(sysUser.getPayBankCard());//银行卡号
                payeeInfo.setName(sysUser.getPayBankUser());
                BankcardExtInfo bankcardExtInfo = new BankcardExtInfo();
                //1：对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号
                //2：对私（在金融机构开设的个人账户）
                bankcardExtInfo.setAccountType("2");
                bankcardExtInfo.setInstName(sysUser.getPayBankName());
//                bankcardExtInfo.setInstBranchName("中国工商银行日新东路支行");
//                bankcardExtInfo.setInstProvince("云南省");
//                bankcardExtInfo.setBankCode("123456");
//                bankcardExtInfo.setInstCity("昆明市");
                payeeInfo.setBankcardExtInfo(bankcardExtInfo);
            } else {
                model.setBusinessParams("{\"payer_show_name_use_alias\":\"false\"}");
                payeeInfo.setIdentity(sysUser.getZhiFuBao());//支付宝账户
//            payeeInfo.setIdentityType("ALIPAY_USER_ID");
                payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
                payeeInfo.setName(sysUser.getZhiFuBaoName());
            }
            model.setPayeeInfo(payeeInfo);
            model.setOrderTitle("易用能零钱提现");
            request.setBizModel(model);
            response = alipayClient.certificateExecute(request);
            System.out.println(response.getBody());
        } catch (AlipayApiException e) {
//            log.error("零钱提现异常原因:" + e.getMessage());
            e.printStackTrace();
            if (type == 1) {
                log.error("分账支付失败！");
                return false;
            } else {
                // 删除提现记录
                baseMapper.deleteById(itemId);
            }
            throw new ServiceException(_classify + "提现失败！");
        }
        if (response.isSuccess()) {
            if (type == 2) {
                // 更新到账情况
                baseMapper.update(null, new UpdateWrapper<UserMoneyItem>()
                        .eq("item_id", itemId).set("state", 2));
                // 更新账户余额
                sysUser.setMoney(sysUser.getMoney().subtract(money));
                sysUserMapper.updateById(sysUser);
            }
        } else {
            if (type == 1) {
                log.error("分账支付失败！" + response.getSubMsg());
                return false;
            } else {
                // 删除提现记录
                baseMapper.deleteById(itemId);
            }
            log.error("提现失败！原因：" + response.getSubMsg());
            throw new ServiceException("提现失败！原因：" + response.getSubMsg());
        }
        return true;
    }

    @Override
    public boolean zfbCash(SysDept sysDept, BigDecimal money, Integer classify, Integer type, Long itemId) {
//        SysDeptInfo deptInfo = sysDeptInfoMapper.selectById(sysDept.getDeptId());
        SysDeptInfo deptInfo = sysDept.getDeptInfo();
        // 暂不开通支付宝转银行卡
        if (classify == 3) {
            return false;
        }
        String _classify = classify == 3 ? "银行卡" :"支付宝";
        if (type == 2) {
            // 生成钱包明细
            UserMoneyItem moneyItem = new UserMoneyItem(sysDept.getDeptId(), sysDept.getDeptName(), 2,
                    "零钱提现", StringUtils.format("零钱提现到{}{}元", _classify, money),
                    2, classify, money, 1);
            baseMapper.insert(moneyItem);
            itemId = moneyItem.getItemId();
        }
        String zfbAppid = sysConfigService.selectConfigByKey("zfb.sh.appid");
        String certPath = sysConfigService.selectConfigByKey("zfb.cert.path");//应用相关支付宝证书存放路径
        String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4pdDiiYJsGkim1auBc1qVzxcdDuPJEwTmTurlwCyHLVNpKNY6I/hhMmvYFTS8ZsnHMWhxuAOhDLMCaPHxNW2T0wxEX8ZXZwxgNW8JHqxILDuRAgGfKK+5NBUZ1ew4oBMZEpDchkqLCwp+eGo8PtCBEZaIe+Iv42VSIs8najv/oPajT0G13CoCUgJhhsh2kZWC6vtm4kR6cSItGvRi847mgAxlQI4HEDG7o0PfvDmAM4ha9DfxTomlkrKhE6NY+Ms7DbmPDyr/YECJ780goYKwS0eSCIOAXdHI84v4mRJpsu5qdzic/ChpD1yaJJ9nXPIX8xMoF6HEM1jgr95+SBwHAgMBAAECggEAdVGlrsn/+/+XOal5Fv7cB2NVJDlZsWBMNKjfxqqboCfEX4R62OYR4m/O5bRTlYEZo15ZJifs5l7TPiy/zKpNvSbTHH5d3xqyWk6ZBgpfHFw+XJwRu7Z2MA5PeeLZ/AB5Ie0R7YvFwSJ6wHBxz2V5xQgPxRgxVov8zHshc8Gj7X6b7WCvNCHZA26lUSU53MHDxivno/tpOAqWhL1rHrwL+vEaoZKkd+P1L8CEbaRH5UpNnm9Pn0ubCxbPcy/Vk4OdsrP6I4eqpkrRU1WZFgmLZZ3iXudrZEnn1QlhZB6Xgu5WyXCFEnSn3Es/3vdARBucLyfUO9ABDmneY6s4aYI6AQKBgQDakuc0OzXzLl1M4uc48b2BX1uEBQkeKI8/xcAZYy6ikSo0xI4P5qYZtxzFQsdJn+pz7CXZGvWHwyaWl94rI8dNf3YYTl0zJ23rrfaN1TaJEB7SLpOm98p8T2YrHqKcAhvgocDtYo5jW7o9PspBg3+ujC2A63zNGUulR5LSUtF7ZwKBgQDYQ8Zbv+SlQvcQrpxYXzreblI/EV2FBqhMpOiNzgAsLgGntOEU28BtxVa2M6aNvtPCY+gBymzpi/JENONgrXCJcuOKFx/BwReEO/yD7rDbIxea1j1eTk9JrWJaOh3WDqFfLx3I+NtJf1IYwK0ls7CafEEZa3NbC+0VC7N5hlaWYQKBgQCVR6/Q5H+8TvY6BN6W7cPYECCY0jef+WOc0pqYvDylmy+QSo4cHhNjjMSBlVI23plqAub2mIsI5if8wkxielUsgNlPUHYm8c8JIA88X1qX0gK62kTNzH7m1/OXj5zPoEEZ8l+pwZ4uDf/sxG2uwPj7ZZHOcwcRrS0U/QUx0I5yEQKBgB9OWFWJxsCBnCBHFozYZD40vCUzD1WlbBGEQcHdUzsSAd1UGs0ZLpb1XSMNAQw91ouqSLiRpAh+4Lgs68lf8g2DmxqvVEKJAC19PYWftOxT/SPF5aZUMbgZqEYlaZJGFeggevBPzfaqvqiko6v0ghkq6YWTf2RrqotEYVuzLa+hAoGBAJ0vHmj9S8oVmgXzj2gznzoMev6KgnMyLnGlmroFKONtipFmL+BYPrx7JDlPOKE7ymtR3c9tojsIfDtuLeICMPpW9UXf2YrwxQBBPXpWHeHdUjCRpsY6cv1vQxiOTAR0Xk7OTDK9XGLJe2esH8+UQG3sXyut2uvkiKFJaJ4tKcg+";
        AlipayFundTransUniTransferResponse response;
        try {
            CertAlipayRequest alipayConfig = new CertAlipayRequest();
            alipayConfig.setPrivateKey(privateKey);
            alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
            alipayConfig.setAppId(zfbAppid);
            alipayConfig.setCharset("UTF8");
            alipayConfig.setSignType("RSA2");
            alipayConfig.setEncryptor("");
            alipayConfig.setFormat("json");
            alipayConfig.setCertPath(certPath + File.separator + "appCertPublicKey.crt");//<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->
            alipayConfig.setAlipayPublicCertPath(certPath + File.separator + "alipayCertPublicKey_RSA2.crt");//"<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->"
            alipayConfig.setRootCertPath(certPath + File.separator + "alipayRootCert.crt");//"<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt -->");
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
            AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
            model.setOutBizNo(String.valueOf(itemId));
            model.setRemark("易用能零钱提现");
            model.setBizScene("DIRECT_TRANSFER");
            Participant payeeInfo = new Participant();
            model.setTransAmount(String.valueOf(money));
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
            if (classify == 3) {
                model.setProductCode("TRANS_BANKCARD_NO_PWD");
                model.setBusinessParams("{\"withdraw_timeliness\":\"T0\"} ");//注意：withdraw_timeliness 为转账到银行卡的预期到账时间，不传默认T+1到账。
                payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
                payeeInfo.setIdentity(deptInfo.getPayBankCard());//银行卡号
                payeeInfo.setName(deptInfo.getPayBankUser());
                BankcardExtInfo bankcardExtInfo = new BankcardExtInfo();
                //1：对公（在金融机构开设的公司账户）,如果银行卡为对公，必须传递省市支行信息或者联行号
                //2：对私（在金融机构开设的个人账户）
                bankcardExtInfo.setAccountType("1");
                bankcardExtInfo.setInstName(deptInfo.getPayBankName());
//                bankcardExtInfo.setInstBranchName("中国工商银行日新东路支行");
//                bankcardExtInfo.setInstProvince("云南省");
//                bankcardExtInfo.setBankCode("123456");
//                bankcardExtInfo.setInstCity("昆明市");
                payeeInfo.setBankcardExtInfo(bankcardExtInfo);
            } else {
                model.setBusinessParams("{\"payer_show_name_use_alias\":\"false\"}");
                payeeInfo.setIdentity(deptInfo.getZhiFuBao());//支付宝账户
//            payeeInfo.setIdentityType("ALIPAY_USER_ID");
                payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
                payeeInfo.setName(deptInfo.getZhiFuBaoName());
            }
            model.setPayeeInfo(payeeInfo);
            model.setOrderTitle("易用能零钱提现");
            request.setBizModel(model);
            response = alipayClient.certificateExecute(request);
            System.out.println(response.getBody());
        } catch (AlipayApiException e) {
//            log.error("零钱提现异常原因:" + e.getMessage());
            e.printStackTrace();
            if (type == 1) {
                log.error("分账支付失败！");
                return false;
            } else {
                // 删除提现记录
                baseMapper.deleteById(itemId);
            }
            throw new ServiceException(_classify + "提现失败！");
        }
        if (response.isSuccess()) {
            if (type == 2) {
                // 更新到账情况
                baseMapper.update(null, new UpdateWrapper<UserMoneyItem>()
                        .eq("item_id", itemId).set("state", 2));
                // 更新账户余额
                sysDept.setMoney(sysDept.getMoney().subtract(money));
                sysDeptMapper.updateById(sysDept);
            }
        } else {
            if (type == 1) {
                log.error("分账支付失败！" + response.getSubMsg());
                return false;
            } else {
                // 删除提现记录
                baseMapper.deleteById(itemId);
            }
            log.error("提现失败！原因：" + response.getSubMsg());
            throw new ServiceException("提现失败！原因：" + response.getSubMsg());
        }
        return true;
    }

    /**
     * 微信提现
     */
    @Override
    public boolean wxCash(SysUser sysUser, BigDecimal money, Integer classify, Integer type) {
//        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        Map<String, String> packageParams = new HashMap<>();
        String xcxAppid = sysConfigService.selectConfigByKey("wx.xcx.appid");
        packageParams.put("mch_appid", xcxAppid); // 微信公众号的appid
        String mch_id = sysConfigService.selectConfigByKey("wx.shh.mchId");
        packageParams.put("mchid", mch_id); // 商务号
        packageParams.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机生成后数字，保证安全性
        packageParams.put("partner_trade_no", WXPayUtil.generateNonceStr()); // 生成商户订单号
        packageParams.put("openid", sysUser.getOpenid()); // 支付给用户openid
        packageParams.put("check_name", "NO_CHECK"); // 是否验证真实姓名呢
//        packageParams.put("re_user_name", re_user_name);// 收款用户姓名
        Double mul = AmountCalUtils.mul(money.doubleValue(), 100);
        String amount = String.valueOf(mul.intValue());
        packageParams.put("amount", amount); // 企业付款金额，单位为分
        packageParams.put("desc", "易用能提现金额到账"); // 企业付款操作说明信息。必填。
//        packageParams.put("spbill_create_ip", spbill_create_ip); // 调用接口的机器Ip地址
        Map<String, String> returnMap;
        try {
            String key = sysConfigService.selectConfigByKey("wx.sh.key");
            // 3.0 利用上面的参数，先去生成自己的签名
            String sign = WXPayUtil.generateSignature(packageParams, key);

            // 4.0 将签名再放回map中，它也是一个参数
            packageParams.put("sign", sign);

            // 5.0将当前的map结合转化成xml格式
            String xml = WXPayUtil.mapToXml(packageParams);

            // 6.0获取需要发送的url地址
            String wxUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 获取退款的api接口


            System.out.println("发送前的xml为：" + xml);

            // 7,向微信发送请求转账请求
            String certPath = sysConfigService.selectConfigByKey("wx.sh.certPath");
            String returnXml = CertHttpUtil.postData(wxUrl, xml, mch_id, certPath);

            System.out.println("返回的returnXml为:" + returnXml);

            // 8，将微信返回的xml结果转成map格式
            returnMap = WXPayUtil.xmlToMap(returnXml);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (type == 1) {
                log.error("分账支付失败！");
                return false;
            }
            throw new ServiceException("微信转账失败！");
        }
        if (returnMap.get("result_code").equals("SUCCESS")) {
            if (type == 2) {
                // 付款成功
                System.out.println("returnMap为:" + returnMap);
                // 生成钱包明细
                UserMoneyItem moneyItem = new UserMoneyItem(sysUser.getUserId(), sysUser.getNickName(), 1,
                        "零钱提现", StringUtils.format("零钱提现到微信{}元", money),
                        2, classify, money, 2);
                baseMapper.insert(moneyItem);
                // 更新账户余额
                sysUser.setMoney(sysUser.getMoney().subtract(money));
                sysUserMapper.updateById(sysUser);
            }
        }else {
            if (type == 1) {
                log.error("分账支付失败！" + returnMap.get("err_code_des"));
                return false;
            }
            throw new ServiceException("提现失败：" + returnMap.get("err_code_des"));
        }
        return true;
    }

}
